home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
4_0
/
SNDLIST-
/
EDIT.C
< prev
next >
Wrap
Text File
|
1988-11-10
|
7KB
|
287 lines
/*
Sound lister
"Edit.c"
*/
#include <DialogMgr.h>
#include <EventMgr.h>
#include <ResourceMgr.h>
#include <SoundMgr.h>
#include <ToolBoxUtil.h>
#include "SndList.h"
/* ----- Globals ------------------------------------------------------- */
unsigned char *Rname; /* Name of resource file */
short Rvolume; /* Volume reference of resource file */
short Level; /* Sound volume level */
Handle Sound; /* Current sound */
short SndId; /* Current 'snd ' resource id */
Fixed *Rate; /* Sampling rate in current sound */
short *Note; /* Base note in current sound */
/* ----- Calculate new rate -------------------------------------------- */
void Calc(rate, base)
Fixed *rate; /* Sampling rate */
short *base; /* Base note */
{
double value, exp2();
value = Fix2X(*rate);
value = value * exp2(5.0 - *base/12.0);
*rate = X2Fix(&value);
*base = 60;
}
/* ----- Filter function for modal dialog ------------------------------ */
static pascal Boolean MyFilter(dialog, event, item)
register DialogPtr dialog;
register EventRecord *event;
register short *item;
{
register unsigned char key;
switch (event->what) {
case updateEvt:
OutLine(dialog, 1, patCopy);
break;
case keyDown:
case autoKey:
key = event->message & charCodeMask;
if (key == '\r' || key == 0x03) {
*item = 1;
return TRUE;
}
if ((key < '0' || key > '9') && key != '.' &&
key != '\t' && key != '\b') {
SysBeep(1);
event->what = nullEvent;
}
break;
}
return FALSE; /* ModalDialog() should handle event */
}
/* ----- Modify the 'snd ' resource in the file ------------------------ */
static short ModifySound()
{
register Fixed rate;
register short note;
register long rateOffset, noteOffset;
register Handle h;
short current, ref, error;
rate = *Rate;
note = *Note;
rateOffset = (Ptr)Rate - *Sound;
noteOffset = (Ptr)Note - *Sound;
DisposHandle(Sound);
if ((ref = OpenResources(Rname, Rvolume, ¤t)) == -1)
return ResError();
if (h = Get1Resource('snd ', SndId)) {
*(Fixed *)(*h + rateOffset) = rate;
*(short *)(*h + noteOffset) = note;
ChangedResource(h);
WriteResource(h);
}
error = ResError();
CloseResources(current, ref);
return error;
}
/* ----- Check 'snd ' resource ----------------------------------------- */
enum {
check_Ok,
check_OpenErr,
check_GetErr,
check_SizeErr,
check_TypeErr,
check_CmdErr
};
static short CheckSound()
{
register Ptr max;
register short *p;
register SoundHeader *q;
register short i, n, command, type;
short current, ref;
if ((ref = OpenResources(Rname, Rvolume, ¤t)) == -1)
return check_OpenErr;
if (Sound = Get1Resource('snd ', SndId)) {
DetachResource(Sound);
HNoPurge(Sound);
HLock(Sound);
}
CloseResources(current, ref);
if (!Sound)
return check_GetErr;
p = (short *)(*Sound);
max = (Ptr)p + GetHandleSize(Sound);
type = *p++; /* Type of 'snd ' resource */
if ((Ptr)p >= max)
return check_SizeErr;
if (type != 1 && type != 2)
return check_TypeErr;
if (type == 1) {
n = *p++; /* Number of modifiers/synthesizers */
if ((Ptr)p >= max)
return check_SizeErr;
p += 3*n; /* Skip resource id/ init parm of mod/synt */
if ((Ptr)p >= max)
return check_SizeErr;
command = bufferCmd | setPtrBit;
}
if (type == 2 ) {
p++; /* Skip reference count */
if ((Ptr)p >= max)
return check_SizeErr;
command = soundCmd | setPtrBit;
}
n = *p++; /* Number of sound commands to follow */
for (i = 0; i < n && (Ptr)p < max; i++) {
if (((SndCommand *)p)->cmd == command) {
q = (SoundHeader *)(*Sound + ((SndCommand *)p)->param2);
if ((Ptr)q < ((Ptr)p + (n-i)*sizeof(SndCommand)) ||
(Ptr)q >= max || (long)q & 1)
return check_SizeErr;
Rate = &(q->sampleRate);
Note = &(q->baseNote);
return check_Ok;
}
p += sizeof(SndCommand)/2;
}
return check_CmdErr;
}
/* ----- Edit 'snd ' resource ------------------------------------------ */
static void EditSound(name, bounds)
unsigned char *name; /* Pascal string */
Rect *bounds;
{
register DialogPtr dialog;
short item;
unsigned char s[256];
unsigned long x;
short error;
short xlevel;
CenterDialog('DLOG', rEdit, bounds);
if (dialog = GetNewDialog(rEdit, 0L, -1L)) {
SetEText(dialog, eName, name);
SndId = Extract(name+1);
error = CheckSound();
if (Sound) {
NumToString((long)(*(short *)*Sound), s);
SetEText(dialog, eType, s);
}
if (!error) {
Fixed2String(*Rate, s);
SetEText(dialog, eRate, s);
NumToString((long)(*Note), s);
SetEText(dialog, eNote, s);
}
ShowWindow(dialog);
OutLine(dialog, 1, patCopy);
do {
ModalDialog(MyFilter, &item);
switch(item) {
case ePlay:
case eOk:
if (Sound) {
if (!error) {
GetEText(dialog, eRate, s);
String2Fixed(s, &x);
if (x > 0x13880000 && x < 0x7FFF0000)
*Rate = x;
Fixed2String(*Rate, s);
SetEText(dialog, eRate, s);
GetEText(dialog, eNote, s);
StringToNum(s, &x);
if (x >= 0 && x < 128)
*Note = (short)x;
NumToString((long)(*Note), s);
SetEText(dialog, eNote, s);
}
if (item == ePlay) {
HideCursor();
GetSoundVol(&xlevel);
SetSoundVol(Level);
SndPlay(0L, Sound, FALSE);
SetSoundVol(xlevel);
ShowCursor();
}
}
break;
case eCalc1:
case eCalc2:
if (!error) {
GetEText(dialog, eNote, s);
StringToNum(s, &x);
if (x >= 0 && x < 128) {
*Note = (short)x;
Calc(Rate, Note);
Fixed2String(*Rate, s);
SetEText(dialog, eRate, s);
NumToString((long)(*Note), s);
SetEText(dialog, eNote, s);
}
}
break;
}
} while (item != eOk && item != eCancel);
DisposDialog(dialog);
if (item == eOk && !error)
ModifySound();
if (Sound)
DisposHandle(Sound);
}
}
/* ----- Edit all selected 'snd ' resources ---------------------------- */
void EditSnds(window)
register DocumentPeek window;
{
register ListHandle list;
Point myCell; /* Current cell */
short length; /* Length of cell entry */
unsigned char fname[256]; /* Name of resource file */
unsigned char name[256]; /* Name of sound resource */
Rect bounds; /* Where to put dialog */
SetPort(window);
bounds = ((WindowPtr)window)->portRect;
LocalToGlobal(&topLeft(bounds));
LocalToGlobal(&botRight(bounds));
GetWTitle(window, fname);
Rname = fname;
Rvolume = window->volume;
Level = 7 - GetCheck(window, iLevel);
list = window->list;
InitCursor();
myCell.v = myCell.h = 0;
while(LGetSelect(TRUE, &myCell, list)) {
length = sizeof(name) - 1;
LGetCell(name+1, &length, myCell, list);
name[0] = length;
EditSound(name, &bounds);
LSetSelect(FALSE, myCell, list); /* De-select the cell */
LNextCell(TRUE, TRUE, &myCell, list);
}
}